﻿
namespace NMemcached.Client.Binary
{
    //Contains all data that can be present in a binary request and response
    internal abstract class BinaryPacket
    {
        /// <summary>
        /// When overridden in a derived class, gets the packet type 
        /// </summary>
        internal abstract PacketType Type { get; }

        /// <summary>
        /// Gets or sets the operation code for the packet
        /// </summary>
        internal OpCode Operation { get; set; }

        /// <summary>
        /// Gets or sets the data type of the packet content
        /// </summary>
        internal DataTypeCode DataType { get; set; }

        /// <summary>
        /// Gets or sets the opaqe value sent to the server with the request
        /// </summary>
        internal uint Opaque { get; set; }

        /// <summary>
        /// Gets or sets the CAS value for check and set operations
        /// </summary>
        internal ulong Cas { get; set; }

        /// <summary>
        /// Gets or sets the key of the packet
        /// </summary>
        internal byte[] Key { get; set; }

        /// <summary>
        /// Gets or sets the extras for the packet
        /// </summary>
        internal byte[] Extras { get; set; }

        /// <summary>
        /// Gets or sets the value of the packet
        /// </summary>
        internal byte[] Value { get; set; }

        /// <summary>
        /// Gets the length of the key of the packet
        /// </summary>
        internal ushort KeyLength
        {
            get
            {
                ushort len = 0;
                if (this.Key != null)
                {
                    len = (ushort)this.Key.Length;
                }
                return len;
            }
        }

        /// <summary>
        /// Gets the length of the extras for the packet
        /// </summary>
        internal byte ExtrasLength
        {
            get
            {
                byte len = 0;
                if (this.Extras != null)
                {
                    len = (byte)this.Extras.Length;
                }
                return len;
            }
        }

        /// <summary>
        /// Gets the total length as a total of the key, extras, and content lengths
        /// </summary>
        internal uint TotalBodyLength
        {
            get
            {
                uint len = (uint)(this.KeyLength + this.ExtrasLength);
                if (this.Value != null)
                {
                    len += (uint)this.Value.Length;
                }
                return len;
            }
        }

        /// <summary>
        /// Initializes a new instance of the BinaryPacket class
        /// </summary>
        protected BinaryPacket()
        {
        }
    }
}
